#include "mt3d.h"

void mt3d::check_validity()
{
    std::map<std::string, complex_d> elem_map;
    std::map<std::string, complex_d>::iterator elem_iter;

    std::clog << "Validitying the kernel matrix ... ";

    std::string tmp_str;
    for (size_t i = 0; i < edge_num_; i++)
    {
        for (Eigen::SparseMatrix<complex_d, Eigen::RowMajor>::InnerIterator it(A_PDE_, i); it; ++it)
        {
            if (it.row() <= it.col()) tmp_str = std::to_string(it.row()) + " " + std::to_string(it.col());
            else tmp_str = std::to_string(it.col()) + " " + std::to_string(it.row());
            
            elem_iter = elem_map.find(tmp_str);

            if (elem_iter != elem_map.end()) // already existed
            {
                if (elem_iter->second != it.value()) // Invalid element
                {
                    throw gctl::runtime_error("The kernel matrix is not symmetirc.");
                    /*
                    std::cout << elem_iter->first << " | " << it.row() << " " << it.col() << " | " << elem_iter->second << " " << it.value();
                    if (edge_on_boundary_[i])
                    {
                        std::cout << " (on boundary)\n";
                    }
                    else std::cout << "\n";
                    */
                }
            }
            else
            {
                elem_map[tmp_str] = it.value();
            }
        }
    }

    /*
    std::map<std::string, complex_d> elem_map;
    std::map<std::string, complex_d>::iterator elem_iter;

    std::string tmp_str;
    for (size_t i = 0; i < edge_num_; i++)
    {
        for (Eigen::SparseMatrix<complex_d>::InnerIterator it(A_PDE_, i); it; ++it)
        {
            if (it.row() <= it.col()) tmp_str = std::to_string(it.row()) + " " + std::to_string(it.col());
            else tmp_str = std::to_string(it.col()) + " " + std::to_string(it.row());
            
            elem_iter = elem_map.find(tmp_str);

            if (elem_iter != elem_map.end()) // already existed
            {
                if (elem_iter->second != it.value()) // Invalid element
                {
                    std::cout << elem_iter->first << " | " << it.row() << " " << it.col() << " | " << elem_iter->second << " " << it.value();
                    if (edge_on_boundary_[i])
                    {
                        std::cout << " (on boundary)\n";
                    }
                    else std::cout << "\n";
                }
            }
            else
            {
                elem_map[tmp_str] = it.value();
            }
        }
    }
    */

    std::clog << "done\n";
    return;
}
